package model; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Observable; import java.util.Observer; import java.util.Set; import controller.GenerateReport; import controller.InputOutput; public class Bank implements Observer, BankProc { private Map<Person, ArrayList<Account>> bank; private Iterator<Person> iterator; private InputOutput inOut = new InputOutput(); private static Bank instance; private GenerateReport generateReport; private Bank() { bank = inOut.deserializeBank(); generateReport = new GenerateReport(); } public static Bank getInstance() { if (instance == null) { instance = new Bank(); } return instance; } @Override public void update(Observable o, Object arg) { System.out.println(((Account) o).toString() + " was modified."); } @Override public void addPerson(Person person) { assert (!bank.containsKey(person)) : "Person already in the bank."; assert (person != null) : "Invalid person."; assert (isWellFormed()) : "Invariant modified."; int size = bank.size(); bank.put(person, null); generateReport.printReport(person, "Wellcome to the bank."); inOut.serializeBank(); assert (bank.size() == size + 1) : "Size of the bank wasn't modified."; assert (isWellFormed()) : "Invariant mofified."; } @Override public void removePerson(Person person) { assert bank.containsKey(person) : "Person not in the bank"; assert (isWellFormed()) : "Invariant mofified."; int size = bank.size(); bank.remove(person); generateReport.printReport(person, "Your account to the bank was deleted."); inOut.serializeBank(); assert (bank.size() == size - 1) : "Size of the bank didn't change."; assert (isWellFormed()) : "Invariant mofified."; } @Override public void addHolderAssociatedAccount(Person person, Account account) { assert (bank.containsKey(person)) : "Person not in the bank."; assert (account.getMoney() >= 0) : "Not a valid sum of money in the account."; assert (isWellFormed()) : "Invariant mofified."; int size; if (bank.get(person) == null) { size = 0; ArrayList<Account> accounts = new ArrayList<>(); accounts.add(account); bank.remove(person); person.setNrOfAccounts(person.getNrOfAccounts() + 1); bank.put(person, accounts); generateReport.printReport(person, "The account " + account + " was added to the bank."); } else { size = bank.get(person).size(); ArrayList<Account> accounts = new ArrayList<>(); accounts.addAll(bank.get(person)); accounts.add(account); bank.remove(person); person.setNrOfAccounts(person.getNrOfAccounts() + 1); bank.put(person, accounts); generateReport.printReport(person, "The account " + account + " was added to the bank."); } inOut.serializeBank(); assert (bank.get(person).size() == size + 1) : "Size of the bank didn't changed."; assert (isWellFormed()) : "Invariant mofified."; } @Override public void removeHolderAssociatedAccount(Person person, Account account) { assert (bank.containsKey(person)) : "Person not in the bank."; assert (bank.get(person).contains(account)) : "Person doesn't have such an account."; assert (isWellFormed()) : "Invariant mofified."; if (bank.containsKey(person)) { int size = bank.get(person).size(); if (person.getNrOfAccounts() > 0) { ArrayList<Account> accounts = bank.get(person); if (accounts.contains(account)) { bank.remove(person); person.setNrOfAccounts(person.getNrOfAccounts() - 1); accounts.remove(account); bank.put(person, accounts); generateReport(person, "The account: " + account + " was deleted."); } } inOut.serializeBank(); assert (bank.get(person).size() == size - 1) : "Size of the bank didn't modified."; assert (isWellFormed()) : "Invariant mofified."; } } @Override public void generateReport(Person person, String message) { generateReport.printReport(person, message); } public Person getCustomer(String userName, String password) { iterator = bank.keySet().iterator(); while (iterator.hasNext()) { Person person = iterator.next(); if (person.getUserName().equals(userName) && person.getPassword().equals(password)) { return person; } } return null; } public ArrayList<Object> getPersonSavingAccounts(Person person) { if (bank.containsKey(person)) { ArrayList<Object> acc = new ArrayList<>(); ArrayList<Account> accounts = bank.get(person); if (accounts == null) { return null; } for (Account account : accounts) { if (account instanceof SavingAccount) acc.add(account); } return acc; } return null; } public ArrayList<Object> getPersonSpendingAccounts(Person person) { if (bank.containsKey(person)) { ArrayList<Object> acc = new ArrayList<>(); ArrayList<Account> accounts = bank.get(person); if (accounts == null) { return null; } for (Account account : accounts) { if (account instanceof SpendingAccount) acc.add(account); } return acc; } return null; } public int getTotalNrOfPersons() { return bank.size(); } public HashMap<Person, ArrayList<Account>> getBankContent() { return (HashMap<Person, ArrayList<Account>>) bank; } public boolean withdrawMoneyFromSpendingAccount(Person person, String accountName, double sumToExtract) { ArrayList<Account> accounts = bank.get(person); Account currentAccount; Iterator<Account> iterator = accounts.iterator(); while (iterator.hasNext()) { currentAccount = iterator.next(); if (currentAccount.getName().equals(accountName) && currentAccount instanceof SpendingAccount) { if (sumToExtract > currentAccount.getMoney()) { return false; } else { currentAccount.setMoney(currentAccount.getMoney() - sumToExtract); inOut.serializeBank(); return true; } } } return false; } public boolean withdrawMoneyFromSavingAccount(Person person, String accountName, double sumToExtract) { ArrayList<Account> accounts = bank.get(person); Account currentAccount; Iterator<Account> iterator = accounts.iterator(); while (iterator.hasNext()) { currentAccount = iterator.next(); if (currentAccount.getName().equals(accountName) && currentAccount instanceof SavingAccount) { if (sumToExtract > currentAccount.getMoney()) { return false; } else { currentAccount.setMoney(currentAccount.getMoney() - sumToExtract); inOut.serializeBank(); return true; } } } return false; } public boolean containsPerson(Person person) { return bank.containsKey(person); } public ArrayList<Object> getAllPersons() { Set<Person> persons = bank.keySet(); ArrayList<Object> pers = new ArrayList<>(); for (Person person : persons) { pers.add(person); } return pers; } public Account getAccount(Person person, String name, double money) { ArrayList<Account> accounts = bank.get(person); for (Account account : accounts) { int result = Double.compare(account.getMoney(), money); if (account.getName().equals(name) && result == 0) { return account; } } return null; } public boolean isWellFormed() { Set<Person> persons = bank.keySet(); Iterator<Person> it = persons.iterator(); while (it.hasNext()) { Person person = it.next(); if (person.getFirstName().equals("") || person.getLastName().equals("")) { return false; } } return true; } }